﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace WSManager.Model
{
    public static class Extensions
    {
        public static Category FindCategory(this IEnumerable<Category> categories, string id, StringComparison options = StringComparison.InvariantCulture)
        {
            Category item = null;

            foreach (var cat in categories)
            {
                if (cat.Id.Equals(id, options))
                {
                    item = cat;
                    break;
                }
                item = cat.Subcategories.FindCategory(id, options);
                if (item != null)
                    break;
            }

            return item;
        }
        public static IEnumerable<Category> Recursive(this IEnumerable<Category> categories)
        {
            return new RecursiveCategoriesEnumerable(categories);
        }

        class RecursiveCategoriesEnumerable : IEnumerable<Category>
        {
            private IEnumerable<Category> categories;
            public RecursiveCategoriesEnumerable(IEnumerable<Category> categories)
            {
                this.categories = categories;
            }

            public IEnumerator<Category> GetEnumerator()
            {
                return new RecursivecategoriesEnumerator(categories);
            }

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
        }

        class RecursivecategoriesEnumerator : IEnumerator<Category>
        {
            private IEnumerable<Category> categories;
            Stack<IEnumerator<Category>> parentStack = new Stack<IEnumerator<Category>>();
            IEnumerator<Category> actual;

            public RecursivecategoriesEnumerator(IEnumerable<Category> categories)
            {
                this.categories = categories;
            }


            public Category Current
            {
                get { return actual.Current; }
            }

            public void Dispose()
            {
                actual.Dispose();
                foreach (var item in parentStack)
                {
                    item.Dispose();
                }
            }

            object System.Collections.IEnumerator.Current
            {
                get { return Current; }
            }

            public bool MoveNext()
            {
                if (actual.Current.Subcategories.Count > 0)
                {
                    parentStack.Push(actual);
                    actual = actual.Current.Subcategories.GetEnumerator();
                }
                if (actual.MoveNext())
                {
                    return true;
                }
                if (parentStack.Count == 0)
                {
                    return false;
                }
                actual = parentStack.Pop();
                return MoveNext();
            }

            public void Reset()
            {
                parentStack.Clear();
                actual = categories.GetEnumerator();
            }
        }


        public static WebImage Load(this WebImage image)
        {
            using (var reader = File.OpenRead(image.Path))
            {
                image.ImageData = new byte[reader.Length];
                reader.Read(image.ImageData, 0, image.ImageData.Length);
            }
            return image;
        }

        public static WebFile Load(this WebFile file)
        {
            using (var reader = File.OpenRead(file.Path))
            {
                file.Data = new byte[reader.Length];
                reader.Read(file.Data, 0, file.Data.Length);
            }
            return file;
        }
    }
}
